package com.pangu.web.handler.admin.shiro;

import com.pangu.web.handler.admin.user.SysMenuEntity;
import com.pangu.web.handler.admin.user.SysRoleEntity;
import com.pangu.web.handler.admin.user.SysUserEntity;
import com.pangu.web.handler.admin.utils.HttpContextUtils;
import com.pangu.web.handler.admin.utils.IPUtils;
import com.pangu.web.service.repository.jpa.SysMenuRepository;
import com.pangu.web.service.repository.jpa.SysRoleRepository;
import com.pangu.web.service.repository.jpa.SysUserRepository;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.tools.ant.taskdefs.condition.Http;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Component
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private SysUserRepository sysUserRepository;
    @Autowired
    private SysMenuRepository sysMenuRepository;

    @Autowired
	private SysRoleRepository sysRoleRepository;

	public static final int SUPER_ADMIN = 1;

    private static final int ACCOUNT_STATUS=0;  //账户锁定

    
    /**
     * 授权(验证权限时调用)
     */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal();
		Set<SysRoleEntity> set=user.getSysRoleEntities();

		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		Set<String> role=new HashSet<>();

		List<String> permsList=new ArrayList<>();
		for( Iterator   it = set.iterator();  it.hasNext(); )
		{
			SysRoleEntity sr=(SysRoleEntity) it.next();
			role.add(sr.getRoleName());

			if(sr.getRoleName().equalsIgnoreCase("admin")){  //系统管理员，拥有所有权限
				List<SysMenuEntity> menuList = sysMenuRepository.findAll();
				for(SysMenuEntity menu : menuList){
					permsList.add(menu.getPerms());
				}
			}else{ //非系统管理员权限 ，根据角色查询菜单

				SysRoleEntity sysRoleEntity= sysRoleRepository.findByRoleName(sr.getRoleName());
				Set<SysMenuEntity> sysMenuEntities=sysRoleEntity.getSysMenuEntities();
				for( Iterator   iterator = sysMenuEntities.iterator();  iterator.hasNext(); ){
					SysMenuEntity sme=(SysMenuEntity) iterator.next();
					permsList.add(sme.getPerms());
				}

			}
		}
		//用户权限列表
		Set<String> permsSet = new HashSet<>();
		for(String perms : permsList){
			if(StringUtils.isBlank(perms)){
				continue;
			}
			permsSet.addAll(Arrays.asList(perms.trim().split(",")));
		}

		info.setRoles(role);
		info.setStringPermissions(permsSet);

		return info;
	}

	/**
	 * 认证(登录时调用)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
		//查询用户信息
		SysUserEntity user = SysUserEntity.of().setUsername(token.getUsername());
		user = sysUserRepository.findSysUserEntityByUsername(user.getUsername());
        
        //账号不存在
        if(user == null) {
            throw new UnknownAccountException("账号或密码不正确");
        }
        if(user.getStatus()==ACCOUNT_STATUS){
        	throw  new LockedAccountException("账号被锁定，请联系管理员!");
		}

		user.setLastLoginIp(IPUtils.getIpAddr(HttpContextUtils.getHttpServletRequest()));
        user.setLastLoginTime(new Date());
		sysUserRepository.save(user);

		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
        return info;
	}

	@Override
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
		shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);
		shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
		super.setCredentialsMatcher(shaCredentialsMatcher);
	}
}
